package xyz.xiaomeiqiu.study;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.params.SetParams;

import java.util.Collections;

@SpringBootApplication
@EntityScan(basePackages = "xyz.xiaomeiqiu.study.domain")
public class App {
    private static final Logger logger = LoggerFactory.getLogger(App.class);

    public static int amount = 10;
    public static void main(String[] args) throws InterruptedException {
//        SpringApplication.run(App.class, args);
        test();
        Thread thread1 = new Thread(() -> test());
        Thread thread2 = new Thread(() -> test());
        thread1.start();
        thread2.start();
        thread1.join();
        thread2.join();

        Thread thread3 = new Thread(() -> test());
        thread3.start();
        thread3.join();
    }

    public static void test() {
        RedisLock redisLock = RedisLock.INSTANCE;
        String lockKey = "test-lock";
        if(!redisLock.lock(lockKey, 10)){
            logger.info("加锁失败");
            return;
        }
        logger.info("加锁成功");

        try {
            // do some thing
            Thread.sleep(5000);
            amount--;
            logger.info("库存剩余:{}", amount);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        if(redisLock.release(lockKey)){
            logger.info("释放锁成功");
        } else {
            logger.info("释放锁失败");
        }

    }

    public static class RedisLock{

        public static final RedisLock INSTANCE = new RedisLock();

        private RedisLock(){}

        private static JedisPool jedisPool = new JedisPool();

        public boolean lock(String lockKey, int expire){
            try(Jedis jedis = jedisPool.getResource()){
                SetParams params = SetParams.setParams().nx().ex(expire);
                return "OK".equals(jedis.set(lockKey, lockKey, params));
            }
        }

        public boolean release(String lockKey){
            String script = "if redis.call('get', KEYS[1])==ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
            try(Jedis jedis = jedisPool.getResource()){
                Object eval = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(lockKey));
                System.out.println("返回结果："+eval);
                return eval.equals(1L);
            }
        }

    }


}